<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>组件</title>
    <script type="text/javascript" src="../assets/vue-2.2.2.js"></script>
    <style>
        .title {
            background: green;
            font-size: 20px;
            width: 80%;
            border-radius: 5px;
            margin: 3px;
        }

        .red{
            color:red;
        }

        .blue{
            color:blue;
        }

        .font30{
            font-size: 30px;
        }
    </style>
</head>

<body>
    <!-------------------------------------------------------------------------------->
    <h4 class="title">1.全局组件和局部组件</h4>
    <div id="app1">
        <my-component></my-component>
        <part-Component></part-Component>
    </div>
    <script>
        //全局组件
        Vue.component("my-component",{
            template:'<div>这是一个全局组件</div>'
        })

        //局部组件
        var partComponent = {
            template:'<div>这是一个局部组件</div>'
        }

        new Vue({
            el: '#app1',
            components : {
                'partComponent':partComponent
            }
        })
    </script>
    <hr>
    <h4 class="title">2.vue组件的模板在某些情况下会受到HTML的限制，比如table只允许是tr、td标签等这些表格元素，所以在table内直接使用组件是无效的，
        可以使用is属性来挂载组件
    </h4>

    <!-------------------------------------------------------------------------------->
    <h4 class="title">3.使用props传递数据</h4>
    <div id="app3">
        <part-Component1 message='来自父组件的数据'></part-Component1>
    </div>
    <script>
        //局部组件
        var partComponent1 = {
            props:['message'],
            template:'<div>{{message}}</div>',
            // data:function(){
            //     return {
            //         message:''
            //     }
            // }
        }

        new Vue({
            el: '#app3',
            components : {
                'partComponent1':partComponent1
            }
        })
    </script>
    <hr>
    <!-------------------------------------------------------------------------------->
    <h4 class="title">4.使用props传递数据(动态数据）</h4>
    <div id="app4">
        <input type="text" v-model="parentMessage">
        <part-Component2 :message='parentMessage'></part-Component2>
    </div>
    <script>
        //局部组件
        var partComponent2 = {
            props: ['message'],
            template: '<div>组件收到的消息：{{message}}</div>',
        }

        var vm4 = new Vue({
            el: '#app4',
            data: {
                parentMessage: '222'
            },
            components: {
                'partComponent2': partComponent2
            }
        })
    </script>
    <hr>

    <!-------------------------------------------------------------------------------->
    <h4 class="title">5.单项数据流</h4>
    <div id="app5">
        <part-Component3 :init-count='1'></part-Component3>
        <part-component4 :width='100'></part-component4>
    </div>

    <script>
        //局部组件
        var partComponent3 = {
            props: ['initCount'],
            template: '<div>组件收到的消息：{{count}}</div>',
            data: function () {
                return {
                    count: this.initCount
                }
            }
        }

        Vue.component('my-component4', {
            props: ['width'],
            template: '<div :style="style">组件内容</div>',
            computed: {
                style: function () {
                    return {
                        width: this.width + 'px'
                    }
                }
            }
        })

        var vm5 = new Vue({
            el: '#app5',
            components: {
                'partComponent3': partComponent3
            }
        })
    </script>
    <hr>

    <!-------------------------------------------------------------------------------->
    <h4 class="title">6.数据验证</h4>
    <hr>

    <!-------------------------------------------------------------------------------->
    <h4 class="title">7.组件通信</h4>
    <span>父子组件通信、兄弟组件通信、跨级组件通信</span>
    <span>v-on除了可以监听Dom事件，还可监听自定义的事件，子组件用$emit()触发事件，父组件用v-on监听子组件的事件</span>

    <div id="app7">
        <p>总数：{{total}}</p>
        <my-component7 @increase="handleGetTotal" @reduce="handleGetTotal"></my-component7>
    </div>
    <script>
        //局部组件
        var myComponent7 = {
            template: `<div>
                    <button @click="handleIncrease">+1</button>
                    <button @click="handleReduce">-1</button>
                </div>`,
            data: function () {
                return {
                    counter: 0
                }
            },
            methods: {
                handleIncrease: function () {
                    this.counter++;
                    this.$emit('increase', this.counter);
                },
                handleReduce: function () {
                    this.counter--;
                    this.$emit('reduce', this.counter);
                }
            }
        }

        new Vue({
            el: '#app7',
            components: {
                'myComponent7': myComponent7
            },
            data: {
                total: 0
            },
            methods: {
                handleGetTotal: function (total) {
                    this.total = total;
                }
            }
        })
    </script>
    <hr>
    <!-------------------------------------------------------------------------------->

    <h4 class="title">8.非父组件通信方法，中央总线方式,适用所有组件通信</h4>
    <span>组件通信还有两种方式：父链和子组件索引</span>
    <div id="app8">
        {{message}}
        <component-A></component-A>
    </div>
    <script>
        var bus = new Vue();
        //局部组件
        var componentA = {
            template: '<button @click="handleEvent">传递事件</button>',
            methods: {
                handleEvent: function () {
                    bus.$emit("on-message", '传递事件')
                }
            }
        }

        var vm8 = new Vue({
            el: '#app8',
            data: {
                message: '吴渣渣'
            },
            components: {
                'componentA': componentA
            },
            mounted() {
                //在实例初始化时，监听来自bus实例的事件
                var _this = this;
                bus.$on('on-message', function (msg) {
                    _this.message = msg;
                });
            },
        })
    </script>
    <hr>
    <!-------------------------------------------------------------------------------->
    <h4 class="title">9.使用solt分发内容（插槽）</h4>

    <!-------------------------------------------------------------------------------->
    <h4 class="title">10.递归组件</h4>
    <div id="app10">
        <child-component></child-component>
    </div>
    <script>
        //全局组件
        Vue.component("child-component", {
            name: 'child-component',
            props: {
                count: {
                    type: Number,
                    default: 1
                }
            },
            template: `<div style="width:80%;height:80px;border:1px solid red;">
                    <child-component :count="count+1" v-if="count < 3"></child-component>
                </div>`
        })

        new Vue({
            el: '#app10',
        })
    </script>
    <hr>

    <!-------------------------------------------------------------------------------->
    <h4 class="title">11.内联模板</h4>
    <div id="app11">
        <child-component1 inline-template>
            <!-- 不会当做内容分发slot,而是作为子组件的模板-->
            <!-- 这里只能有一个根元素-->
            <div>
                <h2>在父组件中定义子组件的模板</h2>
                <p>{{msg}}</p>
                <p>{{message}}</p>
            </div>
        </child-component1>
    </div>
    <script>
        //全局组件
        Vue.component("child-component1", {
            data: function () {
                return {
                    msg: '在子组件声明的数据'
                }
            }
        })

        new Vue({
            el: '#app11',
            data: {
                message: '在父组件声明的数据'
            }
        })
    </script>
    <hr>

    <!-------------------------------------------------------------------------------->
    <h4 class="title">12.动态组件</h4>
    <span>vue提供了一个特殊元素component来动态挂载不同的组件，使用is的特性来选择挂载的组件</span>
    <div id="app12">
        <component :is="currentView"></component>
        <button @click="handleChangeView('comA')">切换到A</button>
        <button @click="handleChangeView('comB')">切换到B</button>
        <button @click="handleChangeView('comC')">切换到C</button>
    </div>
    <script>
        new Vue({
            el: '#app12',
            data: {
                currentView: 'comA'
            },
            components: {
                comA: {
                    template: '<div>组件A</div>'
                },
                comB: {
                    template: '<div>组件B</div>'
                },
                comC: {
                    template: '<div>组件C</div>'
                }
            },
            methods: {
                handleChangeView: function (component) {
                    this.currentView = component;
                }
            }
        })
    </script>
    <hr>

    
</body>

</html>